#include<windows.h>
#ifdef __APPLE__
#include <GLUT/glut.h> // apple path
#else
#include <GL/glut.h> // windows path
#endif

#include <cstdlib> // for exit()
#include <math.h> // for trigonometric functions

int window_id; // window identifier. Set at window creation, used to destroy window at end
int window_width = 256; // window width variable (will be updated by resize function)
int window_height = 256; // window height variable (will be updated by resize function)
float angle = 0.f; // store angle of rotating triangle

void init() // called once just after window setup
{
	glClearColor(0.5f, 0.5f, 0.5f, 0.0); // set clear colour to medium grey
}

void keyboard(unsigned char key, int x, int y) // keyboard callback - called whenever a key is pressed
{
	switch (key) // which key was pressed?
	{
	case 27: glutDestroyWindow(window_id); exit(0); break; // exit cleanly when 'esc' pressed
	}
}

void reshape(int width, int height) // reshape callback - called whenever window size changed
{
	window_width = width; // remember new window width
	window_height = height; // remember new window height
	glViewport(0, 0, window_width, window_height); // set the opengl viewport to full window
	glMatrixMode(GL_PROJECTION); // select the projection matrix for modification
	glLoadIdentity(); // set it to identity matrix (no projection)
	glOrtho(-1, 1, -1, 1, -1, 1); // set up orthographic view from -1 to 1 on all axes
	glMatrixMode(GL_MODELVIEW); // select the modelview matrix for modification
}

void display() // display callback - called whenever window needs redrawing (every frame in our case)
{
	glClear(GL_COLOR_BUFFER_BIT); // clear screen (only colour buffer)
	glLoadIdentity(); // set modelview matrix to identity matrix (no translation, rotation or scaling)
	glRotatef(angle, 0, 0, 1); // change modelview matrix to represent rotation of 'angle' degrees around z-axis
	glBegin(GL_TRIANGLES); // start drawing some triangles
	glColor3f(1, 1, 0); glVertex2f(0.0f, -0.8f); // a yellow vertex
	glColor3f(1, 0, 1); glVertex2f(0.7f, 0.4f); // a magenta vertex
	glColor3f(0, 1, 1); glVertex2f(-0.7f, 0.4f); // a cyan vertex
	glEnd(); // stop drawing stuff
	glutSwapBuffers(); // flip the buffers so we can see what's been drawn
}

void idle() // idle callback - called every frame
{
	angle += 1.f; // rotate the triangle by 1 degree each frame
	glutPostRedisplay(); // tell the OS that window needs to be redrawn
}

int main(int argc, char *argv[]) // main entry point to program
{
	glutInit(&argc, argv); // initialise opengl
	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); // set window display mode (no alpha, double buffered)
	glutInitWindowSize(window_width, window_height); // set initial window size (256,256)
	window_id = glutCreateWindow("evowalker"); // create window with title (remember window id)
	glutKeyboardFunc(keyboard); // function to call when key pressed
	glutReshapeFunc(reshape); // function to call when window resized
	glutDisplayFunc(display); // function to kall when redrawing needed
	glutIdleFunc(idle); // function to call every frame
	init(); // set up our stuff (after opengl and window have been initialised)
	glutMainLoop(); // enter main opengl loop
	return 0; // should never reach here but just to be tidy
}